<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            width: 100%;
            height: 100%;
            background-color: rgba(164, 190, 15, 0.226);
            margin: 0;
            padding: 0;
        }

        .state_box {
            height: 200px;
            margin: 40px;

            display: flex;
            flex-direction: row;
            justify-content: flex-start;
            align-items: center;

        }

        button[disabled] {
            background: #000;
        }

        .state {
            width: 200px;
            height: 200px;
            background: red;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2rem;
            color: #333;
            text-shadow: 1px 1px 0px #fff;
            font-family: Helvetica, sans-serif;
            border: 12px double #ddd;
            transition: all 0.5s ease-in-out;
        }

        button {
            width: 100px;
            height: 50px;
            margin: 10px 0;
            outline: none;
            border: 1px solid #ddd;
            box-shadow: none;
            border-radius: 8px;
            background: rgba(153, 9, 236, 1);
            color: #FFF;
            font-size: 1.2rem;
        }
    </style>
</head>

<body>
    <div class="state_box">
        <div class="state">DOUDOU</div>
        <button data-act="pay">支付</button>
        <button data-act="cancel">取消</button>
        <button data-act="print">取票</button>
    </div>

    <script>
        // let state = "red";
        // const elstate = document.querySelector(".state");

        // document.querySelector("button").addEventListener("click",e=>{
        //     if(state ==="red"){
        //         state = "blue"
        //     }
        //     else if(state ==="blue"){
        //         state ="green"
        //     }
        //     else if(state ==="green"){
        //         state ="red"
        //     }

        //     elstate.style.background = state;
        // })
        //订单已创建,待付款->已付款，待取票(已取消,订单关闭)->已取票（完成）
        class State1 {
            constructor(ctx) {
                this.name = "待支付"
                this.ctx = ctx;
                this.available = ['cancel', 'pay']
            }
            print() {}
            cancel() {
                this.ctx.state = new State3(this.ctx);
            }
            pay() {
                this.ctx.state = new State2(this.ctx);
            }
        }
        class State2 {
            constructor(ctx) {
                this.name = "待出票"
                this.ctx = ctx;
                this.available = ['print']
            }
            print() {
                this.ctx.state = new State4(this.ctx);
            }
            cancel() {}
            pay() {}
        }
        class State3 {
            constructor(ctx) {
                this.name = "订单取消"
                this.ctx = ctx;
                this.available = []
            }
            print() {}
            cancel() {}
            pay() {}
        }
        class State4 {
            constructor(ctx) {
                this.name = "订单完成"
                this.ctx = ctx;
                this.available = []
            }
            print() {}
            cancel() {}
            pay() {}
        }

        class Context {
            constructor() {
                this.state = new State1(this);
            }
            getAvailableActs() {
                return this.state.available;
            }
            getStateName() {
                return this.state.name;
            }
            print() {
                this.state.print();
            }
            cancel() {
                this.state.cancel();
            }
            pay() {
                this.state.pay();
            }
        }

        class Client {
            constructor(btn, elstate, ctx) {
                this.ctx = ctx;
                this.btn = btn;
                this.elstate = elstate;
                this.elstate.innerHTML = ctx.getStateName();
                this.btn.forEach(item => {
                    item.addEventListener("click", this.handleClick.bind(this))
                })

                this.toggleDisable();
            }
            handleClick(e) {
                const act = e.target.dataset.act;
                this.ctx[act]();

                this.elstate.innerHTML = this.ctx.getStateName();
                this.toggleDisable();
            }
            toggleDisable() {
                this.btn.forEach(item => {
                    if (this.ctx.getAvailableActs().includes(item.dataset.act))
                        item.disabled = false
                    else
                        item.disabled = true;
                })
            }
        }

        const btn = Array.from(document.querySelectorAll("button"));
        const state = document.querySelector(".state");
        const ctx = new Context();
        const client = new Client(btn, state, ctx);
    </script>
</body>

</html>